<template>
  <div class="threat-dashboard">
    <div class="dashboard-layout">
      <!-- 左侧列表区域 (90%) -->
      <div class="main-content">
        <div class="controls">
          <div class="search-area">
            <div class="search-item">
              <input
                v-model="filters.keywords"
                placeholder="关键字"
                class="search-input"
              />
            </div>
            <div class="search-item">
              <input
                v-model="filters.method"
                placeholder="方法名称"
                class="search-input"
              />
            </div>
            <div class="search-item">
              <input
                v-model="filters.methodName"
                placeholder="接口名称"
                class="search-input"
              />
            </div>
            <div class="search-item">
              <input
                v-model="filters.linkName"
                placeholder="链路名称"
                class="search-input"
              />
            </div>
            <div class="search-item">
              <input
                v-model="filters.belongtoPrimaryKey"
                placeholder="所属主键"
                class="search-input"
                type="number"
              />
            </div>
            <div class="search-item">
              <input
                v-model="filters.primaryKey"
                placeholder="主键"
                class="search-input"
                type="number"
              />
            </div>
            <div class="search-item">
              <el-select
                v-model="filters.severity"
                placeholder="级别"
                clearable
                size="small"
                class="search-select"
              >
                <el-option
                  v-for="item in severityOptions"
                  :key="item"
                  :label="item"
                  :value="item"
                />
              </el-select>
            </div>
          </div>

          <div class="actions">
            <el-button
              size="large"
              type="primary"
              style="font-size: 11px; height: 28px; line-height: 1;"
              @click="clearFilters"
              >
              重置
            </el-button>
            <el-button
              size="large"
              type="primary"
              style="font-size: 11px; height: 28px; line-height: 1;"
              class="refresh-btn"
              @click="showRefreshDialog"
              >
              自定义刷新
            </el-button>
            <el-button
              size="large"
              type="primary"
              style="font-size: 11px; height: 28px; line-height: 1;"
              class="refresh-btn"
              @click="fetchLogs"
              >
              刷新
            </el-button>
          </div>
        </div>
        
        <div class="table-container">
          <table class="threats-table">
            <thead>
              <tr>
                <th>ID</th>
                <th>方法名称</th>
                <th>接口名称</th>
                <th>链路名称</th>
                <th>所属主键</th>
                <th>主键</th>
                <th>请求方式</th>
                <th>级别</th>
                <th>所属项目</th>
                <th>请求时间</th>
                <th>响应时间</th>
                <th>接口耗时</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="log in displayedThreats" :key="log.id">
                <!-- <td><span :class="['threat-id', getThreatColorClass(log.id.toString())]">{{ log.id }}</span></td> -->
                <td>{{ log.id }}</td>
                <td>{{ log.method }}</td>
                <td>{{ log.method_name }}</td>
                <td>{{ log.link_name }}</td>
                <td>{{ log.belongto_primary_key }}</td>
                <td>{{ log.primary_key }}</td>
                <td>
                  <span :class="['severity', getRequestTypeColorClass(log.type)]">{{ log.type }}</span>
                </td>
                <td>
                  <span :class="['severity', getSeverityColorClass(log.level)]">{{ log.level }}</span>
                </td>
                <td>{{ log.project }}</td>
                <td>{{ log.request_at }}</td>
                <td>{{ log.response_at }}</td>
                <td>
                  <span :class="{'overtime': log.is_overtime}">{{ log.time_consuming }}</span>
                </td>
                <td>
                  <el-button
                    size="small"
                    type="primary"
                    style="font-size: 11px; padding: 1px 6px; height: 20px; margin-right: 4px; line-height: 1;"
                    @click="showDetails(log)"
                  >
                    节点详情
                  </el-button>
                  <el-button
                    type="primary"
                    size="small"
                    @click="showG6Flow(log)"
                  >
                    链路节点
                  </el-button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="table-footer">
          <div class="threats-per-page">
            <span>每页显示：</span>
            <el-select v-model="pageSize" size="small" class="page-size-select">
              <el-option :value="25" label="25条/页" />
              <el-option :value="50" label="50条/页" />
              <el-option :value="100" label="100条/页" />
            </el-select>
          </div>
          <div class="pagination">
            <button @click="previousPage" :disabled="currentPage === 1">Previous</button>
            <span class="page-number">{{ currentPage }}</span>
            <button @click="nextPage" :disabled="currentPage >= totalPages">Next</button>
          </div>
        </div>
      </div>

      <!-- 右侧按钮区域 (10%) -->
      <div class="side-buttons">
        <el-tooltip
          class="box-item"
          effect="dark"
          content="获取指定项目的日志提交记录"
          placement="top-start"
        >
        <div 
          class="stat-card"
          @click="getGitLog"
        >
          <div class="card-icon">
            <svg class="git-icon" viewBox="0 0 24 24" width="32" height="32">
              <path fill="currentColor" d="M2.6,10.59L8.38,4.8l1.69,1.7c-0.24,0.85,0.15,1.78,0.93,2.23v5.54c-0.6,0.34-1,0.99-1,1.73c0,1.1,0.9,2,2,2s2-0.9,2-2c0-0.74-0.4-1.39-1-1.73V9.41l2.07,2.09c-0.07,0.15-0.07,0.32-0.07,0.5c0,1.1,0.9,2,2,2s2-0.9,2-2s-0.9-2-2-2c-0.18,0-0.35,0-0.5,0.07L13.93,7.5C14.23,6.97,14.23,6.3,13.93,5.77l1.69-1.69L21.4,10.59c0.31,0.32,0.31,0.84,0,1.15l-8.38,8.38c-0.32,0.31-0.84,0.31-1.15,0l-8.38-8.38C2.29,11.43,2.29,10.91,2.6,10.59z"/>
            </svg>
          </div>
          <div class="card-content">
            <div class="card-value">Git日志拉取</div>
              <div class="card-subtitle">获取指定项目的日志提交记录</div>
            </div>
          </div>
        </el-tooltip>

        <el-tooltip
          class="box-item"
          effect="dark"
          content="项目中使用到的各类脚本"
          placement="top-start"
        >
          <div 
            class="stat-card"
            @click="handleActionScript"
        >
          <div class="card-icon">
            <svg class="git-icon" viewBox="0 0 24 24" width="32" height="32">
              <path fill="currentColor" d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z"/>
            </svg>
          </div>
          <div class="card-content">
            <div class="card-value">脚本库</div>
              <div class="card-subtitle">项目中使用到的各类脚本</div>
            </div>
          </div>
        </el-tooltip>

        <el-tooltip
          class="box-item"
          effect="dark"
          content="未确定的功能位置"
          placement="top-start"
        >
          <div 
            class="stat-card"
            @click="handleActionWait"
          >
          <div class="card-icon">
            <svg class="git-icon" viewBox="0 0 24 24" width="32" height="32">
              <path fill="currentColor" d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z"/>
            </svg>
          </div>
          <div class="card-content">
            <div class="card-value">待开发</div>
            <div class="card-subtitle">未确定的功能位置</div>
          </div>
        </div>
        </el-tooltip>

        <el-tooltip
          class="box-item"
          effect="dark"
          content="未确定的功能位置"
          placement="top-start"
        >
          <div 
            class="stat-card"
            @click="handleActionWait"
          >
          <div class="card-icon">
            <svg class="git-icon" viewBox="0 0 24 24" width="32" height="32">
              <path fill="currentColor" d="M14.6,16.6L19.2,12L14.6,7.4L16,6L22,12L16,18L14.6,16.6M9.4,16.6L4.8,12L9.4,7.4L8,6L2,12L8,18L9.4,16.6Z"/>
            </svg>
          </div>
          <div class="card-content">
            <div class="card-value">待开发</div>
            <div class="card-subtitle">未确定的功能位置</div>
            </div>
          </div>
        </el-tooltip>
      </div>
    </div>

    <node-detail-drawer
      v-model="detailsDrawer.visible"
      :node-id="detailsDrawer.nodeId"
    />

    <el-drawer
      v-model="chainItemDetailsDrawer.visible"
      :title="chainItemDetailsDrawer.title"
      size="60%"
      :append-to-body="true"
    >
      <div class="drawer-container has-mermaid">
        <div class="detail-content">
          <div class="api-info-section">
            <div class="info-item">
              <div class="label">POST</div>
              <div class="value">{{ chainItemDetailsDrawer.data?.type }}</div>
            </div>
            
            <div class="info-item">
              <div class="label">文件地址</div>
              <div class="value">{{ chainItemDetailsDrawer.data?.url }}</div>
              <el-button
                type="primary"
                size="small"
                class="copy-btn"
                @click="copyToClipboard(chainItemDetailsDrawer.data?.url || '')"
              >
                Copy
              </el-button>
            </div>
            
            <div class="info-item">
              <div class="label">接口URL</div>
              <div class="value">{{ chainItemDetailsDrawer.data?.router }}</div>
              <el-button
                type="primary"
                size="small"
                class="copy-btn"
                @click="copyToClipboard(chainItemDetailsDrawer.data?.router || '')"
              >
                Copy
              </el-button>
            </div>
            
            <div class="info-item">
              <div class="label">请求参数</div>
              <div class="json-viewer">
                <vue-json-pretty
                  v-if="chainItemDetailsDrawer.data?.request_params"
                  :data="parseJsonSafely(chainItemDetailsDrawer.data.request_params)"
                  :deep="3"
                  :showLength="true"
                  :showLine="true"
                  :showDoubleQuotes="true"
                  :path="'res'"
                  :selectableType="'single'"
                  class="json-viewer-content"
                />
              </div>
              <el-button
                type="primary"
                size="small"
                class="copy-btn"
                @click="copyToClipboard(JSON.stringify(parseJsonSafely(chainItemDetailsDrawer.data?.request_params), null, 2))"
              >
                Copy
              </el-button>
            </div>
            
            <div class="info-item">
              <div class="label">响应参数</div>
              <div class="json-viewer">
                <vue-json-pretty
                  v-if="chainItemDetailsDrawer.data?.response_params"
                  :data="parseJsonSafely(chainItemDetailsDrawer.data.response_params)"
                  :deep="3"
                  :showLength="true"
                  :showLine="true"
                  :showDoubleQuotes="true"
                  :path="'res'"
                  :selectableType="'single'"
                  class="json-viewer-content"
                />
              </div>
              <el-button
                type="primary"
                size="small"
                class="copy-btn"
                @click="copyToClipboard(JSON.stringify(parseJsonSafely(chainItemDetailsDrawer.data?.response_params), null, 2))"
              >
                Copy
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-drawer>

    <el-dialog
      v-model="refreshDialog.visible"
      title="设置列表刷新间隔时间"
      width="400px"
    >
      <el-form :model="refreshDialog.form" label-width="100px">
        <el-form-item label="时间值" required>
          <el-input-number
            v-model="refreshDialog.form.value"
            :min="0"
            controls-position="right"
            style="width: 200px;"
          />
        </el-form-item>
        
        <el-form-item label="时间类型" required>
          <el-select
            v-model="refreshDialog.form.type"
            style="width: 200px;"
          >
            <el-option label="秒" value="second" />
            <el-option label="分钟" value="minute" />
            <el-option label="小时" value="hour" />
          </el-select>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="stopRefresh">停 止</el-button>
          <el-button type="primary" @click="startRefresh">开 始</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- Git 日志弹窗 -->
    <el-dialog
      v-model="gitLogDialog.visible"
      title="Git 日志"
      width="40%"
      :close-on-click-modal="false"
    >
      <div class="git-log-dialog">
        <!-- 目录路径部分 -->
        <div class="paths-section">
          <h3>日志目录路径：</h3>
          <ul class="path-list">
            <li v-for="(path, index) in gitLogDialog.paths" :key="index">
              {{ index + 1 }}. {{ path }}
            </li>
          </ul>
        </div>
        
        <!-- 作者输入框 -->
        <div class="author-section">
          <el-input
            v-model="gitLogDialog.author"
            placeholder="请输入作者名称"
            clearable
            size="default"
          >
            <template #prepend>作者</template>
          </el-input>
        </div>
        
        <!-- 日志信息部分 -->
        <div class="logs-section">
          <div class="section-header">
            <h3>日志信息：</h3>
            <el-button
              type="primary"
              size="small"
              :loading="gitLogDialog.loading"
              @click="fetchGitLogs"
            >
              获取
            </el-button>
          </div>
          
          <div v-loading="gitLogDialog.loading" class="log-content">
            <template v-if="gitLogDialog.logs.length > 0">
              <div v-for="(log, index) in gitLogDialog.logs" :key="index" class="log-item">
                {{ log }}
              </div>
            </template>
            <div v-else class="no-logs">
              暂无日志信息
            </div>
          </div>
        </div>
      </div>
    </el-dialog>

    <LinkFlowDrawer
      v-model="linkFlowDrawer.visible"
      :link-id="linkFlowDrawer.linkId"
      @node-click="handleNodeClick"
    />

    <G6FlowDrawer
      v-model="g6FlowDrawer.visible"
      :link-id="g6FlowDrawer.linkId"
    />

    <ScriptLibraryDrawer
      v-model="scriptLibraryDrawer.visible"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import { ElButton, ElDrawer, ElSelect, ElOption, ElDialog, ElForm, ElFormItem, ElInputNumber } from 'element-plus'
import axios from 'axios'
import type { LogItem, LogResponse } from '@/types/log'
import VueJsonPretty from 'vue-json-pretty'
import 'vue-json-pretty/lib/styles.css'
import { ElMessage } from 'element-plus'
import { Plus, Upload, Download, Delete } from '@element-plus/icons-vue'
import LinkFlowDrawer from '@/components/LinkFlowDrawer.vue'
import G6FlowDrawer from '@/components/G6FlowDrawer.vue'
import NodeDetailDrawer from '@/components/NodeDetailDrawer.vue'
import ScriptLibraryDrawer from '@/components/ScriptLibraryDrawer.vue'
import { API_URL } from '@/utils/config'
const pageSize = ref(30)
const currentPage = ref(1)
const total = ref(0)
const logs = ref<LogItem[]>([])

const filters = ref({
  method: '',
  methodName: '',
  belongtoPrimaryKey: '',
  primaryKey: '',
  severity: '',
  keywords: '',
  linkName: ''
})

const severityOptions = ['INFO', 'ERROR']

const displayedThreats = computed(() => logs.value)

const totalPages = computed(() => Math.ceil(total.value / pageSize.value))

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
    fetchLogs()
  }
}

const previousPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--
    fetchLogs()
  }
}

const clearFilters = () => {
  filters.value = {
    method: '',
    methodName: '',
    belongtoPrimaryKey: '',
    primaryKey: '',
    severity: '',
    keywords: '',
    linkName: ''
  }
  fetchLogs()
}

interface LogDetails extends LogItem {
  url?: string
  router?: string
  request_params?: any
  response_params?: any
  mermaid_content?: string
}

interface DrawerState {
  visible: boolean
  title: string
  data: LogDetails | null
}

const detailsDrawer = ref({
  visible: false,
  nodeId: ''
})

const chainDrawer = ref<DrawerState>({
  visible: false,
  title: '威胁链路',
  data: null
})

const chainItemDetailsDrawer = ref<DrawerState>({
  visible: false,
  title: '链路项详情',
  data: null
})

const showDetails = (row: LogItem) => {
  if (row.node_id) {
    detailsDrawer.value.nodeId = row.node_id
    detailsDrawer.value.visible = true
  }
}

const refreshDialog = ref({
  visible: false,
  form: {
    value: 0,
    type: 'second'
  }
})

let refreshInterval: number | null = null

const showRefreshDialog = () => {
  refreshDialog.value.visible = true
}

const startRefresh = () => {
  stopRefresh()
  
  const interval = calculateInterval(
    refreshDialog.value.form.value,
    refreshDialog.value.form.type
  )
  
  refreshInterval = window.setInterval(() => {
    fetchLogs()
  }, interval)
  
  refreshDialog.value.visible = false
}

const stopRefresh = () => {
  if (refreshInterval) {
    clearInterval(refreshInterval)
    refreshInterval = null
  }
  refreshDialog.value.visible = false
}

const calculateInterval = (value: number, type: string): number => {
  const multipliers = {
    second: 1000,
    minute: 60 * 1000,
    hour: 60 * 60 * 1000
  }
  return value * multipliers[type as keyof typeof multipliers]
}

const fetchLogs = async () => {
  try {
    const response = await axios.get<LogResponse>(`${API_URL}/logs`, {
      params: {
        pageNum: currentPage.value,
        pageSize: pageSize.value,
        method: filters.value.method || undefined,
        method_name: filters.value.methodName || undefined,
        belongto_primary_key: filters.value.belongtoPrimaryKey || undefined,
        primary_key: filters.value.primaryKey || undefined,
        level: filters.value.severity || undefined,
        keywords: filters.value.keywords || undefined,
        link_name: filters.value.linkName || undefined
      }
    })
    
    if (response.data.code === 0) {
      logs.value = response.data.data.items
      total.value = response.data.data.total
    }
  } catch (error) {
    console.error('获取日志数据失败:', error)
  }
}

const copyToClipboard = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text)
    ElMessage.success('复制成功')
  } catch (err) {
    ElMessage.error('复制失败')
  }
}

const parseJsonSafely = (value: any): any => {
  if (!value) return {};
  if (typeof value === 'string') {
    try {
      return JSON.parse(value);
    } catch (e) {
      return value;
    }
  }
  return value;
};

onMounted(() => {
  fetchLogs()
})


const getRequestTypeColorClass = (type: string) => {
  const typeMap: Record<string, string> = {
    'GET': 'blue',  // 默认颜色（蓝色）
    'POST': 'green',  // 绿色
    'PUT': 'yellow',   // 黄色
    'DELETE': 'red', // 红色
    'PATCH': 'gray'     // 灰色
  }
  return typeMap[type] || 'info'
}

const getSeverityColorClass = (level: string) => {
  const levelMap: Record<string, string> = {
    'INFO': 'green',
    // 'ERROR': 'blue',
    'ERROR': 'red',
  }
  return levelMap[level] || 'green'
}

watch(filters, () => {
  currentPage.value = 1
  fetchLogs()
}, { deep: true })

// 添加按钮处理函数
const getGitLog = () => {
  showGitLogDialog()
}

const handleActionScript = () => {
  scriptLibraryDrawer.value.visible = true
}

const handleActionWait = () => {
  ElMessage.warning('功能开发中')
  console.log('Action 2 clicked')
}

// 监听链路详情抽屉的可见性变化
watch(() => chainItemDetailsDrawer.value.visible, (newVal) => {
  if (newVal && chainItemDetailsDrawer.value.data) {
    nextTick(() => {
      mermaid.init(undefined, '.mermaid')
    })
  }
})

// 第一个处理函数
const handleNodeClick = (nodeId) => {
  // 处理节点点击事件
  console.log('Node clicked in parent:', nodeId)
  // 这里可以添加你的业务逻辑，比如：
  // - 显示节点详情
  // - 导航到其他页面
  // - 打开弹窗等
}

interface GitLogResponse {
  code: number
  data: string[]
  msg: string
}

// Git 日志弹窗数据
const gitLogDialog = ref({
  visible: false,
  loading: false,
  author: localStorage.getItem('git_author') || '',
  paths: [
    '/home/wwwroot/card',
    '/home/wwwroot/qst-card',
    '/home/wwwroot/qst-business-card-api',
    '/home/wwwroot/qst-business-card-new'
  ],
  logs: [] as string[]
})

// 获取 Git 日志
const fetchGitLogs = async () => {
  if (!gitLogDialog.value.author.trim()) {
    ElMessage.warning('请输入作者名称')
    return
  }

  gitLogDialog.value.loading = true
  try {
    const response = await axios.get<GitLogResponse>(`${API_URL}/git/logs`, {
      params: {
        address: gitLogDialog.value.paths.join('|'),
        author: gitLogDialog.value.author
      }
    })
    
    if (response.data.code === 0) {
      gitLogDialog.value.logs = response.data.data
    }
  } catch (error) {
    console.error('获取Git日志失败:', error)
  } finally {
    gitLogDialog.value.loading = false
  }
}

// 监听作者名称变化，保存到本地存储
watch(() => gitLogDialog.value.author, (newVal) => {
  localStorage.setItem('git_author', newVal)
})

// 显示 Git 日志弹窗
const showGitLogDialog = () => {
  gitLogDialog.value.visible = true
}

const linkFlowDrawer = ref({
  visible: false,
  linkId: null
})

const g6FlowDrawer = ref({
  visible: false,
  linkId: null as string | null
})

const showG6Flow = (row: LogItem) => {
  if (row && row.link_id && row.link_id !== '0') {
    g6FlowDrawer.value.linkId = row.link_id
    g6FlowDrawer.value.visible = true
  } else {
    ElMessage.warning('链路ID不存在')
  }
}

const scriptLibraryDrawer = ref({
  visible: false
})
</script>

<style scoped>
#app {
  margin: 8px;
}

.threat-dashboard {
  width: 100%;
  height: 100vh;
  margin: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}


.dashboard-layout {
  display: flex;
  width: 100%;
  height: calc(100% - 16px);
  overflow: hidden;
}

.main-content {
  flex: 0 0 90%;
  max-width: 88%;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.controls {
  margin-bottom: 3px;
  display: flex;
  /* justify-content: space-between; */
  align-items: center;
  gap: 15px;
}

.refresh-btn {
  margin-left: 2px;
}

.search-area {
  display: flex;
  gap: 20px;
  /* flex: 1; */
}

.search-item {
  flex: 1;
}

.search-input {
  width: 100%;
  padding: 2px 8px;
  font-size: 11px;
  border: 1px solid #dcdfe6;
  border-radius: 3px;
  height: 22px;
}

.search-input:focus {
  outline: none;
  border-color: #409eff;
}

.search-select {
  width: 100%;
  font-size: 11px;
  border-radius: 3px;
  height: 28px;
}

.search-select :deep(.el-select__wrapper) {
  min-height: 28px;
}

.search-select :deep(.is-transparent) {
  color: #666;
  font-size: 11px;
}

/* 保持原有表格样式 */
.threats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.threats-table th,
.threats-table td {
  padding: 2px 2px;
  border: 1px solid #e0e0e0;
  text-align: left;
  line-height: 1.2;
}

.threats-table th {
  background-color: #f5f5f5;
  font-weight: normal;
  color: #666;
}

.table-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 3px;
  /* padding: 8px 0; */
  /* border-top: 1px solid #e6e6e6; */
}

.threats-per-page {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
}

.page-size-select {
  width: 100px;
}

.pagination {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pagination button {
  padding: 2px 8px;
  font-size: 11px;
  border: 1px solid #dcdfe6;
  background-color: white;
  border-radius: 4px;
  cursor: pointer;
}

.page-number {
  font-size: 11px;
}

.side-buttons {
  flex: 0 0 10%;
  max-width: 10%;
  margin-top: 21px;
  padding: 10px;
  background-color: #ffffff;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.stat-card {
  background: #ffffff;
  border-radius: 2px;
  padding: 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  border: 1px solid #f0f0f0;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: #f5f7fa;
  flex-shrink: 0;
}

.git-icon {
  width: 24px;
  height: 24px;
  color: #333;
}

.card-content {
  flex: 1;
  min-width: 0;
}

.card-title {
  font-size: 12px;
  color: #909399;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-value {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 2px;
}

.card-subtitle {
  font-size: 11px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 保持原有的其他样式 */
.severity {
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 11px;
  color: white;
}

.overtime {
  color: red;
}

.severity.blue { background-color: #3498db; }
.severity.red { background-color: #f56c6c; }
.severity.green { background-color: #67c23a; }

.threat-id {
  font-family: monospace;
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 11px;
  display: inline-block;
  color: white;
  border: none;
}

.threat-id.blue { background-color: #3498db; }
.threat-id.purple { background-color: #9b59b6; }
.threat-id.green { background-color: #2ecc71; }
.threat-id.orange { background-color: #e67e22; }
.threat-id.teal { background-color: #16a085; }

.threats-table tbody tr:nth-child(even) {
  background-color: #fafafa;
}

.threats-table tbody tr:hover {
  background-color: #f0f0f0;
}

:deep(.el-input__wrapper) {
  padding: 0 8px;
}

:deep(.el-input__inner) {
  height: 22px;
  font-size: 11px;
}

:deep(.el-select-dropdown__item) {
  font-size: 11px;
  padding: 0 8px;
  height: 24px;
  line-height: 24px;
}

/* 抽屉组件样式 */
.drawer-content {
  padding: 16px;
  font-size: 11px;
}

.detail-table {
  width: 100%;
  border-collapse: collapse;
}

.detail-table td {
  padding: 4px 6px;
  border: 1px solid #e0e0e0;
  line-height: 1.2;
}

.detail-table .label {
  width: 120px;
  background-color: #f5f5f5;
  font-weight: normal;
  color: #666;
}

.detail-table .value {
  word-break: break-all;
}

/* Element Plus 抽屉样式覆盖 */
:deep(.el-drawer__header) {
  margin-bottom: 0;
  padding: 12px 16px;
  font-size: 13px;
  border-bottom: 1px solid #e0e0e0;
}

:deep(.el-drawer__body) {
  padding: 0;
}

/* API信息区域样式 */
.api-info-section {
  padding: 20px;
}

.info-item {
  margin-bottom: 24px;
  position: relative;
}

.info-item .label {
  font-weight: 600;
  margin-bottom: 8px;
  color: #333;
  font-size: 14px;
}

.info-item .value {
  background: #f5f7fa;
  padding: 8px 12px;
  border-radius: 4px;
  font-family: monospace;
  font-size: 13px;
  color: #444;
  word-break: break-all;
}

.copy-btn {
  position: absolute;
  right: 8px;
  top: 32px;
  font-size: 12px;
  padding: 4px 12px;
}

.json-viewer {
  background: #f5f7fa;
  padding: 16px;
  border-radius: 4px;
  margin-top: 8px;
  max-height: 400px;
  overflow-y: auto;
}

.json-viewer-content {
  font-size: 13px !important;
}

:deep(.vjs-tree) {
  font-size: 13px;
  font-family: monospace;
  background-color: transparent !important;
}

:deep(.vjs-tree .vjs-value__string) {
  color: #c41a16 !important;
}

:deep(.vjs-tree .vjs-value__number) {
  color: #1a1aa6 !important;
}

:deep(.vjs-tree .vjs-value__boolean) {
  color: #0000ff !important;
}

:deep(.vjs-tree .vjs-value__null) {
  color: #808080 !important;
}

:deep(.vjs-tree .vjs-key) {
  color: #881391 !important;
}

:deep(.vjs-tree .vjs-value__undefined) {
  color: #808080 !important;
}

/* 链路图相关样式 */
.drawer-container {
  height: 100%;
}

.drawer-container.has-mermaid {
  display: flex;
  gap: 24px;
}

.detail-content {
  flex: 1;
  overflow-y: auto;
}

/* 确保嵌套抽屉的层级正确 */
.el-drawer {
  &.is-append-to-body {
    z-index: 3000;
  }
}

/* 链路项详情抽屉样式 */
.chain-item-details {
  padding: 16px;
}

/* 确保嵌套抽屉中的表格样式与主列表一致 */
:deep(.el-drawer__body) .threats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}

:deep(.el-drawer__body) .threats-table th,
:deep(.el-drawer__body) .threats-table td {
  padding: 4px 6px;
  border: 1px solid #e0e0e0;
  text-align: left;
  line-height: 1.2;
}

:deep(.el-drawer__body) .threats-table th {
  background-color: #f5f5f5;
  font-weight: normal;
  color: #666;
}

:deep(.el-drawer__body) .threats-table tbody tr:nth-child(even) {
  background-color: #fafafa;
}

:deep(.el-drawer__body) .threats-table tbody tr:hover {
  background-color: #f0f0f0;
}

/* 保持 threat-id 和 severity 样式一致 */
:deep(.el-drawer__body) .threat-id {
  font-family: monospace;
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 11px;
  display: inline-block;
  color: white;
  border: none;
}

:deep(.el-drawer__body) .severity {
  padding: 1px 4px;
  border-radius: 2px;
  font-size: 11px;
}

/* 确保链路项详情抽屉样式与主详情抽屉一致 */
:deep(.el-drawer__body) .api-info-section {
  padding: 20px;
}

:deep(.el-drawer__body) .info-item {
  margin-bottom: 24px;
  position: relative;
}

:deep(.el-drawer__body) .info-item .label {
  font-weight: 600;
  margin-bottom: 8px;
  color: #333;
  font-size: 14px;
}

:deep(.el-drawer__body) .info-item .value {
  background: #f5f7fa;
  padding: 8px 12px;
  border-radius: 4px;
  font-family: monospace;
  font-size: 13px;
  color: #444;
  word-break: break-all;
}

:deep(.el-drawer__body) .copy-btn {
  position: absolute;
  right: 8px;
  top: 32px;
  font-size: 12px;
  padding: 4px 12px;
}

:deep(.el-drawer__body) .json-viewer {
  background: #f5f7fa;
  padding: 16px;
  border-radius: 4px;
  margin-top: 8px;
  max-height: 400px;
  overflow-y: auto;
}

:deep(.el-drawer__body) .json-viewer-content {
  font-size: 13px !important;
}

/* 保持 JSON 查看器样式一致 */
:deep(.el-drawer__body) .vjs-tree {
  font-size: 13px;
  font-family: monospace;
  background-color: transparent !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-value__string {
  color: #c41a16 !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-value__number {
  color: #1a1aa6 !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-value__boolean {
  color: #0000ff !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-value__null {
  color: #808080 !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-key {
  color: #881391 !important;
}

:deep(.el-drawer__body) .vjs-tree .vjs-value__undefined {
  color: #808080 !important;
}

/* 链路详情抽屉的 Mermaid 图表样式 */
.drawer-container.has-mermaid {
  display: flex;
  gap: 24px;
  height: 100%;
}

.detail-content {
  flex: 1;
  overflow-y: auto;
  padding-right: 16px;
}

.mermaid-content {
  flex: 1;
  padding: 16px;
  border-left: 1px solid #f0f0f0;
  overflow-y: auto;
}

.mermaid {
  width: 100%;
  height: 100%;
  background-color: white;
  padding: 16px;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.git-log-dialog {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.paths-section {
  padding: 16px;
  background: #f8f9fa;
  border-radius: 4px;
}

.paths-section h3 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #333;
}

.path-list {
  margin: 0;
  padding: 0 0 0 20px;
  list-style: none;
}

.path-list li {
  font-family: monospace;
  font-size: 13px;
  color: #444;
  line-height: 1.8;
}

.logs-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.section-header h3 {
  margin: 0;
  font-size: 14px;
  color: #333;
}

.log-content {
  min-height: 300px;
  max-height: 500px;
  overflow-y: auto;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 4px;
}

.log-item {
  font-family: monospace;
  font-size: 12px;
  color: #444;
  padding: 4px 0;
  white-space: pre-wrap;
  word-break: break-all;
}

.log-item:not(:last-child) {
  border-bottom: 1px dashed #e0e0e0;
}

.no-logs {
  text-align: center;
  color: #909399;
  padding: 40px 0;
}

:deep(.el-dialog__body) {
  padding: 0 20px 20px;
}

:deep(.el-form-item__content) {
  height: 32px;
}
:deep(.el-input__inner) {
  height: 32px;
}

.author-section {
  /* padding: 0 16px; */
}

.author-section :deep(.el-input-group__prepend) {
  width: 60px;
  text-align: center;
  font-weight: 500;
  color: #606266;
}

/* 调整间距 */
.git-log-dialog {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.paths-section {
  padding: 16px;
  background: #f8f9fa;
  border-radius: 4px;
}

.mermaid {
  padding: 20px;
}

/* 添加表格容器样式 */
.table-container {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 3px;
}

/* 修改 .threats-table 的样式 */
.threats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

/* 固定表头 */
.threats-table thead {
  position: sticky;
  top: 0;
  background: white;
  z-index: 1;
}
</style> 